package com.springboot.onlinemusicserver.service.imp;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.fasterxml.jackson.databind.util.BeanUtil;
import com.springboot.onlinemusicserver.mapper.UserMapper;
import com.springboot.onlinemusicserver.model.LoginUser;
import com.springboot.onlinemusicserver.model.User;
import com.springboot.onlinemusicserver.service.UserService;
import com.springboot.onlinemusicserver.utils.common.CheckParam;
import com.springboot.onlinemusicserver.utils.common.Encrypt;
import com.springboot.onlinemusicserver.utils.common.SpecialCharacters;
import com.springboot.onlinemusicserver.utils.common.Result;
import com.springboot.onlinemusicserver.utils.req.UserLoginParam;
import com.springboot.onlinemusicserver.utils.req.UserRegisterParam;
import jakarta.annotation.Resource;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpSession;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Service;

import java.util.List;

import static com.springboot.onlinemusicserver.utils.common.SessionAttribute.USERINFO;

/**
 * Created with IntelliJ IDEA.
 * Description :
 * User: jiume
 * Date: 2025-05-18
 * Time: 19:03
 */
@Slf4j
@Service
public class UserServiceImp implements UserService {

    @Resource
    private UserMapper userMapper;

    @Override
    public Result<Boolean> userLogin(UserLoginParam userLoginParam, HttpServletRequest request) {
        // 1、判断参数是否合法
        if (!CheckParam.checkLoginParamIsBlank(userLoginParam)) {
            log.info("[userLogin]: 参数不合法");
            return Result.error("参数不合法", false);
        }
        // 2、判断用户名和密码的长度是否小于6位
        String userName = userLoginParam.getUserName();
        String password = userLoginParam.getPassword();
        if (!CheckParam.checkLoginParamLength(userName, password)) {
            log.info("[userLogin]: 用户名或密码的长度小于6");
            return Result.error("用户名或密码的长度小于6", false);
        }
        // 3、判断用户名是否包含特殊字符
        boolean result = SpecialCharacters.Contains(userName);
        if (!result) {
            log.info("[userLogin]: 用户名包含特殊字符");
            return Result.error("用户名包含特殊字符", false);
        }
        // 4、根据用户名去查询数据库，看是否存在该用户
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        // select * from user where user_name = 'zhangsan';
        queryWrapper.eq(User::getUserName, userName);
        List<User> users = userMapper.selectList(queryWrapper);
        // 注册阶段的判断，已经注定数据库中不可能存在两个同名的用户
        if (users.size() != 1) {
            log.info("[userLogin]: "+userName+" 不存在");
            return Result.error(userName+" 不存在", false);
        }
        // 5、将数据库中的密码和用户输入的密码进行比对，看是否一致
        User user = users.get(0);
        if (!Encrypt.matches(password, user.getPassword())) {
            log.info("[userLogin]: 密码错误");
            return Result.error("密码错误", false);
        }
        // 6、将用户信息脱敏并存储到session中
        // 用户信息脱敏
        LoginUser loginUser = new LoginUser();
        BeanUtils.copyProperties(user, loginUser);
        HttpSession session = request.getSession();
        session.setAttribute(USERINFO, loginUser);
        log.info("[userLogin]: "+userName+" 登录成功");
        return Result.success(true);
    }

    @Override
    public Result<Boolean> userRegister(UserRegisterParam userRegisterParam) {
        // 1、校验参数是否合法(包含密码和确认密码是否一致)
        if (!CheckParam.checkRegisterParamIsBlank(userRegisterParam)) {
            log.info("[userRegister]: 参数不合法");
            return Result.error("参数不合法", false);
        }
        String userName = userRegisterParam.getUserName();
        String password = userRegisterParam.getPassword();
        String checkPassword = userRegisterParam.getCheckPassword();
        if (!password.equals(checkPassword)) {
            log.info("[userRegister]: 密码和确认密码不一致");
            return Result.error("密码和确认密码不一致", false);
        }
        // 2、校验用户名、密码、确认密码的长度是否小于6位
        if (!CheckParam.checkRegisterParamLength(userName, password, checkPassword)) {
            log.info("[userRegister]: 用户名或密码或确认密码的长度小于6位");
            return Result.error("用户名或密码或确认密码的长度小于6位", false);
        }
        // 3、校验用户名是否包含特殊字符
        if (!SpecialCharacters.Contains(userName)) {
            log.info("[userRegister]: 用户名包含特殊字符");
            return Result.error("用户名包含特殊字符", false);
        }
        // 3、根据用户名查询数据库，看该用户名是否已经注册过
        LambdaQueryWrapper<User> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(User::getUserName, userName);
        List<User> users = userMapper.selectList(queryWrapper);
        if (users.size() != 0) {
            log.info("[userRegister]: "+userName+" 已经注册过");
            return Result.error(userName+" 已经注册过", false);
        }
        // 4、将密码加密和用户名一起存储到数据库中
        String newPassword = Encrypt.encode(password);
        User user = new User();
        user.setUserName(userName);
        user.setPassword(newPassword);
        int result = userMapper.insert(user);
        if (result != 1) {
            log.info("[userRegister]: 注册失败");
            return Result.error("注册失败", false);
        }
        log.info("[userRegister]: "+userName+" 注册成功");
        return Result.success(true);
    }
}
